/*
 * @Author: 孟庆晨
 * @Date: 2021-06-04 20:08:51
 * @LastEditTime: 2023-03-10 14:41:16
 * @LastEditors: mengqingchen mengqc1995@163.com
 * @Description:axios 封装
 * @FilePath: \vite-vue3-ts\src\utils\axios.ts
 * 道法自然
 */
import axios from 'axios'
import Cookies from 'js-cookie'
import router from '../router'

// 接口错误情况处理
const errorHandler = (err: any) => {
  // 从pendingRequest对象中移除请求
  removePendingRequest(err.config || {})
  if (axios.isCancel(err)) {
    console.log('已取消的重复请求：' + err.message)
  } else {
    // 添加异常处理
  }
  console.log(err)
  return Promise.reject(err)
}

const service = axios.create({
  // import.meta.env.MODE === 'development' 来判断是否开发环境
  withCredentials: false, // cookie
  baseURL: '/dev-api',
  timeout: 100000
})

function getRequestKey(config: any) {
  const { method, url, params, data } = config
  return [method, url, JSON.stringify(params), JSON.stringify(data)].join('&')
}

// 添加请求信息
const pendingRequest = new Map()
function addPendingRequest(config: any) {
  const requestKey = getRequestKey(config)
  config.cancelToken =
    config.cancelToken ||
    new axios.CancelToken((cancel: any) => {
      if (!pendingRequest.has(requestKey)) {
        pendingRequest.set(requestKey, cancel)
      }
    })
}

// 取消重复请求，移除重复请求信息
function removePendingRequest(config: any) {
  const requestKey = getRequestKey(config)
  if (pendingRequest.has(requestKey)) {
    // 如果是重复的请求，则执行对应的cancel函数
    const cancel = pendingRequest.get(requestKey)
    cancel(requestKey)
    // 将前一次重复的请求移除
    pendingRequest.delete(requestKey)
  }
}

service.interceptors.request.use(
  (config: any) => {
    // 检查是否存在重复请求，若存在则取消已发的请求
    removePendingRequest(config)
    // 把当前请求信息添加到pendingRequest对象中
    addPendingRequest(config)

    if (config.data && config.data.post) {
      if (config.method === 'post') {
        config.data.post = null
        config.params = config.data
      }
    }

    return config
  },
  (error: any) => {
    console.log(error)
    // return Promise.reject()
  }
)

service.interceptors.response.use((response: any) => {
  // 从pendingRequest对象中移除请求
  removePendingRequest(response.config)

  // application/octet-stream
  // 只将请求结果的data字段返回(JSON格式处理)
  let resData
  if (typeof response.data === 'string' && /{/.test(response.data)) {
    try {
      resData = JSON.parse(response.data)
    } catch (e) {
      resData = response.data
    }
  } else {
    resData = response.data
  }
  // 如果自定义代码不是20000，则判断为错误.
  if (resData.code && resData.code != 200 && resData.code !== true) {
    // 50008: 非法token; 50012: 其他客户端已登录; '505': Token 已过期; 401资源认证失败
    if (resData.code == 505 || resData.code == 506 || resData.code == 401) {
      // to re-login

      Cookies.remove('Admin-Token')
      setTimeout(() => {
        router.replace({ path: '/education' })
      }, 1000)
    }
    return Promise.reject(new Error(resData.msg || 'Error'))
  }
  return resData
}, errorHandler)

export default service
